const BindingX = uni.requireNativePlugin('bindingx');
const dom = uni.requireNativePlugin('dom');
const animation = uni.requireNativePlugin('animation');

export default {
    data() {
        return {
            right: 0,
            button: [],
            preventGesture: false
        }
    },

    watch: {
        show(newVal) {
            if (!this.position || JSON.stringify(this.position) === '{}') return;
            if (this.autoClose) return
            if (this.isInAnimation) return
            if (newVal) {
                this.open()
            } else {
                this.close()
            }
        },
    },
    created() {
        if (this.swipeaction.children !== undefined) {
            this.swipeaction.children.push(this)
        }
    },
    mounted() {
        this.boxSelector = this.getEl(this.$refs['selector-box-hock']);
        this.selector = this.getEl(this.$refs['selector-content-hock']);
        this.buttonSelector = this.getEl(this.$refs['selector-button-hock']);
        this.position = {}
        this.x = 0
        setTimeout(() => {
            this.getSelectorQuery()
        }, 200)
    },
    beforeDestroy() {
        if (this.timing) {
            BindingX.unbind({
                token: this.timing.token,
                eventType: 'timing'
            })
        }
        if (this.eventpan) {
            BindingX.unbind({
                token: this.eventpan.token,
                eventType: 'pan'
            })
        }
        this.swipeaction.children.forEach((item, index) => {
            if (item === this) {
                this.swipeaction.children.splice(index, 1)
            }
        })
    },
    methods: {
        onClick(index, item) {
            this.$emit('click', {
                content: item,
                index
            })
        },
        touchstart(e) {
            if (this.isInAnimation) return
            if (this.stop) return
            this.stop = true
            if (this.autoClose) {
                this.swipeaction.closeOther(this)
            }
            let endWidth = this.right
            let boxStep = `(x+${this.x})`
            let pageX = `${boxStep}> ${-endWidth} && ${boxStep} < 0?${boxStep}:(x+${this.x} < 0? ${-endWidth}:0)`

            let props = [{
                element: this.selector,
                property: 'transform.translateX',
                expression: pageX
            }]

            let left = 0
            for (let i = 0; i < this.options.length; i++) {
                let buttonSelectors = this.getEl(this.$refs['button-hock'][i]);
                if (this.button.length === 0 || !this.button[i] || !this.button[i].width) return
                let moveMix = endWidth - left
                left += this.button[i].width
                let step = `(${this.x}+x)/${endWidth}`
                let moveX = `(${step}) * ${moveMix}`
                let pageButtonX = `${moveX}&& (x+${this.x} > ${-endWidth})?${moveX}:${-moveMix}`
                props.push({
                    element: buttonSelectors,
                    property: 'transform.translateX',
                    expression: pageButtonX
                })
            }

            this.eventpan = this._bind(this.boxSelector, props, 'pan', (e) => {
                if (e.state === 'end') {
                    this.x = e.deltaX + this.x;
                    if (this.x < -endWidth) {
                        this.x = -endWidth
                    }
                    if (this.x > 0) {
                        this.x = 0
                    }
                    this.stop = false
                    this.bindTiming();
                }
            })
        },
        touchend(e) {
            this.$nextTick(() => {
                if (this.isopen && !this.isDrag && !this.isInAnimation) {
                    this.close()
                }
            })
        },
        bindTiming() {
            if (this.isopen) {
                this.move(this.x, -this.right)
            } else {
                this.move(this.x, -40)
            }
        },
        move(left, value) {
            if (left >= value) {
                this.close()
            } else {
                this.open()
            }
        },
        /**
         * 开启swipe
         */
        open() {
            this.animation(true)
        },
        /**
         * 关闭swipe
         */
        close() {
            this.animation(false)
        },
        /**
         * 开启关闭动画
         * @param {Object} type
         */
        animation(type) {
            this.isDrag = true
            let endWidth = this.right
            let time = 200
            this.isInAnimation = true;

            let exit = `t>${time}`;
            let translate_x_expression = `easeOutExpo(t,${this.x},${type ? (-endWidth - this.x) : (-this.x)},${time})`
            let props = [{
                element: this.selector,
                property: 'transform.translateX',
                expression: translate_x_expression
            }]

            let left = 0
            for (let i = 0; i < this.options.length; i++) {
                let buttonSelectors = this.getEl(this.$refs['button-hock'][i]);
                if (this.button.length === 0 || !this.button[i] || !this.button[i].width) return
                let moveMix = endWidth - left
                left += this.button[i].width
                let step = `${this.x}/${endWidth}`
                let moveX = `(${step}) * ${moveMix}`
                let pageButtonX = `easeOutExpo(t,${moveX},${type ? -moveMix + '-' + moveX : 0 + '-' + moveX},${time})`
                props.push({
                    element: buttonSelectors,
                    property: 'transform.translateX',
                    expression: pageButtonX
                })
            }

            this.timing = BindingX.bind({
                eventType: 'timing',
                exitExpression: exit,
                props: props
            }, (e) => {
                if (e.state === 'end' || e.state === 'exit') {
                    this.x = type ? -endWidth : 0
                    this.isInAnimation = false;

                    this.isopen = this.isopen || false
                    if (this.isopen !== type) {
                        this.$emit('change', type)
                    }
                    this.isopen = type
                    this.isDrag = false
                }
            });
        },
        /**
         * 绑定  BindingX
         * @param {Object} anchor
         * @param {Object} props
         * @param {Object} fn
         */
        _bind(anchor, props, eventType, fn) {
            return BindingX.bind({
                anchor,
                eventType,
                props
            }, (e) => {
                typeof (fn) === 'function' && fn(e)
            });
        },
        /**
         * 获取ref
         * @param {Object} el
         */
        getEl(el) {
            return el.ref
        },
        /**
         * 获取节点信息
         */
        getSelectorQuery() {
            dom.getComponentRect(this.$refs['selector-content-hock'], (data) => {
                if (this.position.content) return
                this.position.content = data.size
            })
            for (let i = 0; i < this.options.length; i++) {
                dom.getComponentRect(this.$refs['button-hock'][i], (data) => {
                    if (!this.button) {
                        this.button = []
                    }
                    if (this.options.length === this.button.length) return
                    this.button.push(data.size)
                    this.right += data.size.width
                    if (this.autoClose) return
                    if (this.show) {
                        this.open()
                    }
                })
            }
        }
    }
}
